import 'package:flutter/material.dart';
import 'package:my_app_01/utils/index.dart';

class TagSelect extends StatefulWidget {
  // 绑定值
  dynamic value; // List or String

  // 选项
  List options;

  // 字段名称配置
  Map<String, String>? fieldNames;

  // 是否多选
  bool multiple;

  // 是否可清除
  bool clearable;

  // 是否禁用
  bool disabled;

  // 选择框默认文字
  String placeholder;

  double? width;
  double? height;

  // 值变动后事件
  final ValueChanged<dynamic>? onChanged;

  removeItemByIndex(index) {
    options.removeAt(index);
    if (onChanged != null) {
      onChanged!(value);
    }
  }

  checkItemByIndex(index) {
    var current = options[index]?.toJson()[fieldNames?['value']];
    if (multiple) {
      if (value == null) {
        value = [current];
      } else {
        int i = value.indexWhere((e) => e == current);
        if (i == -1) {
          value.add(current);
        } else {
          value.removeAt(i);
        }
      }
    } else {
      value = current;
    }
    if (onChanged != null) {
      onChanged!(value);
    }
  }

  TagSelect({
    super.key,
    // 默认选中
    this.value,
    // 标签选项列表
    required this.options,
    // 字段名称配置
    this.fieldNames = const {
      "value": "id",
      "label": "name",
    },
    // 是否多选
    this.multiple = true,
    this.clearable = false,
    this.disabled = false,
    this.placeholder = "请选择",
    this.width = double.infinity,
    this.height = 60,
    this.onChanged,
  });

  @override
  State<TagSelect> createState() => _TagSelectState();
}

class _TagSelectState extends State<TagSelect> {
  // 检查是否已选
  bool isChecked(
    String current,
  ) {
    if (widget.value == null) return false;
    if (widget.multiple) {
      return widget.value.any((e) => e == current);
    } else {
      return widget.value == current;
    }
  }

  @override
  Widget build(BuildContext context) {
    // 将options过滤转化为map形式，防止因格式不统一造成报错
    var list = widget.options!.map((v) => v.toJson()).toList().asMap();
    return Wrap(
      children: list.entries.map((e) {
        var current = e.value;

        return TagItem(
          name: current[widget.fieldNames?['label']],
          index: e.key,
          data: current,
          isChecked: isChecked(current[widget.fieldNames?['value']]),
          removeItemByIndex: (index) {
            setState(() {
              widget.removeItemByIndex(index);
            });
          },
          checkItemByIndex: (index) {
            setState(() {
              widget.checkItemByIndex(index);
            });
          },
        );
      }).toList(),
    );
  }
}

class TagItem extends StatelessWidget {
  // 是否被选中
  bool isChecked;

  // 该项标签对应数据label
  String name;

  // 存放该项标签对应数据
  dynamic data;

  // 该项标签对应列表中下标
  int? index;

  // 标签高度
  double? height;

  EdgeInsets? padding;

  EdgeInsets? margin;

  // 边框样式
  ShapeBorder? shapeBorder;

  // 是否可关闭
  bool? closeable;

  // 是否禁用
  bool? disabled;

  // 删除某项
  Function? removeItemByIndex;

  // 选择某项
  Function? checkItemByIndex;

  TagItem({
    Key? key,
    this.isChecked = false,
    required this.name,
    this.data,
    this.index,
    this.padding = const EdgeInsets.only(left: 8, right: 8),
    this.margin = const EdgeInsets.all(4),
    this.shapeBorder = const RoundedRectangleBorder(
      borderRadius: BorderRadius.all(Radius.circular(4)),
    ),
    this.height = 28,
    this.closeable = false,
    this.disabled = false,
    this.removeItemByIndex,
    this.checkItemByIndex,
  }) : super(key: key);

  static var defaultColor = const Color.fromRGBO(12, 170, 145, 1);
  static var defaultBkColor = const Color.fromRGBO(100, 247, 255, .05);

  static var activeColor = Colors.white;
  static var activeBkColor = const Color.fromRGBO(12, 170, 145, 1);

  @override
  Widget build(BuildContext context) {
    return InkWell(
      onTap: () {
        if (disabled!) return;
        if (closeable!) {
          MUtils.showCupertinoAlertDialog(context, title: "删除", content: "确定要删除该标签吗？", confirm: () {
            removeItemByIndex != null && removeItemByIndex!(index);
          });
        } else {
          checkItemByIndex != null && checkItemByIndex!(index);
        }
      },
      child: Container(
        padding: padding,
        height: height,
        margin: margin,
        // alignment: Alignment.center,
        decoration: BoxDecoration(
          color: isChecked ? activeBkColor : defaultBkColor,
          border: Border.all(width: 1, color: defaultColor),
          borderRadius: const BorderRadius.all(Radius.circular(6)),
        ),
        child: Row(
          mainAxisSize: MainAxisSize.min,
          children: [
            Text(
              name,
              style: TextStyle(
                fontSize: 12,
                color: isChecked ? activeColor : defaultColor,
              ),
            ),
            closeable!
                ? Padding(
                    padding: const EdgeInsets.only(left: 6),
                    child: Icon(
                      Icons.cancel,
                      size: 14,
                      color: isChecked ? activeColor : defaultColor,
                    ),
                  )
                : const SizedBox(),
          ],
        ),
      ),
    );
  }
}
